package com.kashow.base.rx;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.trello.rxlifecycle.LifecycleTransformer;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Singleton;

import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.subscriptions.CompositeSubscription;

/**
 * 用于管理RxBus的事件和Rxjava相关代码的生命周期处理
 */
@Singleton
public class RxManager {
    @Inject
    public RxManager () {
        super();
    }
    public RxBus mRxBus = RxBus.$();
    private Map<Object, Observable<?>> mObservables = new HashMap<>();// 管理观察源
    private Map<Object,CompositeSubscription> mCompositeSubscriptions = new HashMap<>();
    private CompositeSubscription mCompositeSubscription = new CompositeSubscription();// 管理订阅者者

    /****
     * 通过RxBus监听tag标签对应的事件
     * @param tag
     * @param action1
     */
    public void on(Object tag, Action1<Object> action1) {
        Observable<?> mObservable = mRxBus.register(tag);
        mObservables.put(tag, mObservable);
        mCompositeSubscription.add(mObservable.observeOn(AndroidSchedulers.mainThread())
                .subscribe(action1, (e) -> e.printStackTrace()));
    }



    public void single (Object tag, Action1<Object> action1) {
        unregister(tag);
        Observable<?> mObservable = mRxBus.register(tag);
        mObservables.put(tag, mObservable);
        mCompositeSubscription.add(mObservable.observeOn(AndroidSchedulers.mainThread())
                .subscribe(action1, (e) -> e.printStackTrace()));
    }



    /****
     * 通过RxBus监听tag标签对应的事件
     * @param tag
     * @param lifecycleTransformer
     * @param action1
     */
    public void on(Object tag, LifecycleTransformer <Object> lifecycleTransformer, Action1<Object> action1) {
        Observable<?> mObservable = mRxBus.register(tag);
        mObservables.put(tag, mObservable);
        mCompositeSubscription.add(mObservable
                .compose(lifecycleTransformer)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(action1,throwable -> {throwable.printStackTrace();}));
    }

    /****
     * 通过RxBus监听tag标签对应单事件
     * @param tag
     * @param lifecycleTransformer
     * @param action1
     */
    public void single (Object tag, LifecycleTransformer <Object> lifecycleTransformer, Action1<Object> action1) {
        unregister(tag);
        Observable<?> mObservable = mRxBus.register(tag);
        mObservables.put(tag, mObservable);
        mCompositeSubscription.add(mObservable
                .compose(lifecycleTransformer)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(action1,throwable -> {throwable.printStackTrace();}));
    }

    /****
     * 为指定对象添加订阅者
     * @param tag
     * @param m
     */
    public void addSubscription(Object tag, Subscription m) {
        CompositeSubscription compositeSubscription = mCompositeSubscriptions.get(tag);
        if (compositeSubscription == null) {
            compositeSubscription = new CompositeSubscription();
            mCompositeSubscriptions.put(tag,compositeSubscription);
        }
        compositeSubscription.add(m);
    }

    /****
     * 移除指定对象所有的订阅者
     * @param tag
     * @param
     */
    public void removeSubscriptions(@NonNull Object tag) {
        if (!mCompositeSubscriptions.containsKey(tag)) {
            return;
        }
        CompositeSubscription compositeSubscription = mCompositeSubscriptions.get(tag);
        if (compositeSubscription != null && compositeSubscription.hasSubscriptions()) {
            compositeSubscription.unsubscribe();
            compositeSubscription.clear();
        }
        mCompositeSubscriptions.remove(tag);
    }

    /***
     * 为指定对象的指定订阅者
     * @param tag
     * @param m
     */
    public void removeSubscription(@NonNull Object tag,@Nullable Subscription m) {
        CompositeSubscription compositeSubscription = mCompositeSubscriptions.get(tag);
        if (compositeSubscription != null && compositeSubscription.hasSubscriptions()) {
            compositeSubscription.remove(m);
            mCompositeSubscriptions.remove(tag);
        }
    }

    /****
     * 移除RxBus所有监听事件
     */
    public void clear() {
        mCompositeSubscription.unsubscribe();// 取消订阅
        for (Map.Entry<Object, Observable<?>> entry : mObservables.entrySet()) {
            mRxBus.unregister(entry.getKey(), entry.getValue());// 移除观察
        }
        mObservables.clear();
    }


    /****
     * 反注册tag标签对应的事件
     * @param tag
     */
    public void unregister(@NonNull Object tag) {
        Observable<?> observable = mObservables.get(tag);
        if (observable != null) {
            unregister(tag,observable);
        }
    }

    /****
     *
     * @param tag
     * @param observable
     */
    public void unregister(@NonNull Object tag,
                           @NonNull Observable<?> observable) {
        mRxBus.unregister(tag,observable);
    }

    /****
     * 触发tag标签对应的事件
     * @param tag
     * @param content
     */
    public void post(Object tag, Object content) {
        mRxBus.post(tag, content);
    }
}
